package com.example.demo.utils;

import lombok.extern.slf4j.Slf4j;


import java.io.File;
import java.io.FileWriter;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;

/***
 * 自动生成controller service repostity entity
 */
@Slf4j
public class CodeGenerator {
    private static String dbUrl = "jdbc:mysql://8.139.4.71:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true";//更换
    private static String dbUsername = "ydd";
    private static String dbPassword = "ydd123";
    private static String basePackage = "com.example.demo";//需要更换

    private static String entity = "entity";//model可换成pojo,entity----com.edge.user.model 有些是pojo,有些是entity

    public static String getCreatePath() {
        return "src\\main\\java." + basePackage;
    }

    public static void main(String[] args) {
//        create("review_content");//数据库表
//        create("review_node");//数据库表
//        create("review_record");//数据库表
//        create("review_record_log");//数据库表
        create("role");//数据库表
    }

    /***
     * 表字段备注
     * @param conn
     * @param tableName
     * @return
     * @throws SQLException
     */
    public static Map<String, String> getColumnRemarks(Connection conn, String tableName) throws SQLException {
        DatabaseMetaData metaData = conn.getMetaData();
        ResultSet rs = metaData.getColumns(null, null, tableName, null);

        Map<String, String> columnRemarks = new HashMap<>();
        while (rs.next()) {
            String columnName = rs.getString("COLUMN_NAME");
            String remarks = rs.getString("REMARKS");
            columnRemarks.put(columnName, remarks);
        }

        return columnRemarks;
    }

    public static void create(String tableName) {
        if (tableName.equals("")) {
            return;
        }
        if (tableName == null) {
            return;
        }
//        generateEntity(tableName);
//        log.info("------------------{}--创建entity--------------", tableName);
        generateService(tableName);
//        log.info("------------------{}--创建service--------------", tableName);
//        generateController(tableName);
//        log.info("------------------{}--创建controller-------------", tableName);
//        generateRepository(tableName);
//        log.info("------------------{}--创建repository-------------", tableName);
    }

    /***
     * 生成实体类
     * @param tableName
     */
    public static void generateEntity(String tableName) {
        try (Connection conn = DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
             Statement stmt = conn.createStatement()) {
            ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName + " LIMIT 1");
            Map<String, String> columnRemarks = getColumnRemarks(conn, tableName);

            ResultSetMetaData metaData = rs.getMetaData();
            StringBuilder entityCode = new StringBuilder();
            entityCode.append("package ").append(basePackage).append("." + entity + ";\n\n\n\n");

            entityCode.append("import lombok.Data;\n" +
                    "import com.baomidou.mybatisplus.annotation.IdType;\n"
                    + "import com.baomidou.mybatisplus.annotation.TableField;\n" +
                    "import com.baomidou.mybatisplus.annotation.TableId;\n" +
                    "import com.baomidou.mybatisplus.annotation.TableName;\n" +
                  "\n\n\n\n");
            entityCode.append("@Data\n");

            entityCode.append("@Table(value =").append("\"" + tableName + "\"").append(")\n");
            entityCode.append("public class ").append(tableNameToClassName(tableName)).append("Entity").append(" {\n");
            for (int i = 1; i <= metaData.getColumnCount(); i++) {
                String columnName = metaData.getColumnName(i);
                String columnType = metaData.getColumnTypeName(i);
                String remark = columnRemarks.get(columnName);
                if (columnName.equals("id")) {
                    entityCode.append("     @TableId(value = \"id\", type = IdType.AUTO)\n");

                }
//                if (columnName.equals("create_time")) {
//                    entityCode.append("      @Temporal(TemporalType.TIMESTAMP)\n" +
//                            "    @CreatedDate\n");
//                }
//                entityCode.append("    @Column(name =\"" + columnName + "\")\n");


                entityCode.append("    private ").append(mapColumnType(columnType)).append(" ").append(convert(columnName)).append(";\n\n");
            }
            entityCode.append("}");

            saveToFile(entityCode.toString(), getSavePath(getCreatePath(), entity), tableNameToClassName(tableName) + "Entity" + ".java");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static String convert(String input) {

        StringBuilder stringBuilder = new StringBuilder();

        // 将字符串按照"_"分割成多个部分
        String[] parts = input.split("_");

        for (int i = 0; i < parts.length; i++) {
            String part = parts[i];

            if (i == 0) {
                // 第一个部分保持不变
                stringBuilder.append(part);
            } else {
                // 首字母大写，其余字符小写
                stringBuilder.append(Character.toUpperCase(part.charAt(0)));
                stringBuilder.append(part.substring(1).toLowerCase());
            }
        }

        return stringBuilder.toString();

    }

    /***
     * 生成Service
     * @param tableName
     */
    public static void generateService(String tableName) {
        String className = tableNameToClassName(tableName);
        StringBuilder serviceCode = new StringBuilder();

        serviceCode.append("package ").append(basePackage + ".").append("service;\n\n");
        serviceCode.append("import ").append(basePackage + ".").append(entity + ".").append(className).append("Entity;\n");
        serviceCode.append("import ").append(basePackage + ".").append("repository.").append(className).append("Repository;\n");
        serviceCode.append("import org.springframework.stereotype.Service;\n\n\n\n");
        serviceCode.append("@Service\n");

        serviceCode.append("public class ").append(className).append("Service extends BaseService<").append(className).append("Entity,").append(className + "Repository>{\n");
        serviceCode.append("\n\n");
        serviceCode.append("}");

        saveToFile(serviceCode.toString(), getSavePath(getCreatePath(), "service"), className + "Service.java");
    }

    /****
     * 生成controller
     *
     * @param tableName
     */
    public static void generateController(String tableName) {
        String className = tableNameToClassName(tableName);
        StringBuilder controllerCode = new StringBuilder();

        controllerCode.append("package ").append(basePackage).append(".controller;\n\n\n\n");


        controllerCode.append("import org.springframework.stereotype.Controller;\n" +
                "import org.springframework.web.bind.annotation.RequestMapping;\n\n\n\n");


        controllerCode.append("@RequestMapping(\"/" + tableName + "\") \n");
        controllerCode.append("@Controller \n");
        controllerCode.append("public class ").append(className).append("Controller {\n");
        controllerCode.append("\n");
        controllerCode.append("\n");
        controllerCode.append("}");

        saveToFile(controllerCode.toString(), getSavePath(getCreatePath(), "controller"), className + "Controller.java");
    }

    /***
     * 生成Repository
     * @param tableName
     */
    public static void generateRepository(String tableName) {
        String className = tableNameToClassName(tableName);
        StringBuilder repository = new StringBuilder();
        repository.append("package ").append(basePackage).append(".mapper;\n\n");
        //import com.edge.user.model.ReviewRecordCopyEntity;
        repository.append("import ").append(basePackage + ".").append(entity + ".").append(className).append("Entity;\n");
        repository.append("import com.baomidou.mybatisplus.core.mapper.BaseMapper;\n");
        repository.append("import org.apache.ibatis.annotations.Mapper;\n\n\n\n\n\n");
        repository.append("@Mapper \n");
        repository.append("public interface ").append(className).append("Mapper extends BaseMapper<" + className + "Entity>{\n");
        repository.append("\n");
        repository.append("}");
        saveToFile(repository.toString(), getSavePath(getCreatePath(), "mapper"), className + "Mapper.java");
    }

    /***
     * 表名->类名
     * @param tableName
     * @return
     */
    public static String tableNameToClassName(String tableName) {
        String[] parts = tableName.split("_");
        StringBuilder className = new StringBuilder();
        for (String part : parts) {
            className.append(Character.toUpperCase(part.charAt(0)))
                    .append(part.substring(1));
        }
        return className.toString();
    }

    /***
     * 数据库字段对应类型
     * @param columnType
     * @return
     */
    public static String mapColumnType(String columnType) {
        // Map database column types to Java types
        if (columnType.equalsIgnoreCase("int")) {
            return "Integer";
        } else if (columnType.equalsIgnoreCase("bigint")) {
            return "Long";
        } else if (columnType.equalsIgnoreCase("varchar") || columnType.equalsIgnoreCase("text")) {
            return "String";
        } else if (columnType.equalsIgnoreCase("datetime")) {
            return "Date";
        } else if (columnType.equalsIgnoreCase("decimal")) {
            return "BigDecimal";

        }
        return "Object";
    }

    public static void saveToFile(String code, String path, String fileName) {
        try {
            File directory = new File(path);
            if (!directory.exists()) {
                directory.mkdirs();
            }
            FileWriter writer = new FileWriter(directory.getPath() + File.separator + fileName);
            writer.write(code);
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static String getSavePath(String basePackage, String subPackage) {
        String packagePath = basePackage.replace(".", File.separator);
        return System.getProperty("user.dir") + File.separator + packagePath + File.separator + subPackage;
    }

}


